﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using YogaStudio.Data;
using YogaStudio.Data.Domain;
using YogaStudio.Service.BLL;
using YogaStudio.WebUI.Models;

namespace YogaStudio.WebUI.Controllers
{
    public class SectionsController : Controller
    {
        private YogaStudioEntities db = new YogaStudioEntities();
        private ISectionService sectionService = new SectionService();
        private FacultySerivce facultyService = new FacultySerivce();
        Faculty _currentFaculty;
        public Faculty CurrentFaculty
        {
            get
            {
                return _currentFaculty ?? (_currentFaculty = facultyService.GetFacultyByLogInUserName(User.Identity.Name));
            }
        }

        // GET: Sections
        public ActionResult Index()
        {
            var sections = db.Sections.Include(s => s.Course).Include(s => s.Faculty).Include(s => s.Room).Include(s => s.Schedule);
            return View(sections.ToList());
        }

        // GET: Sections
        public ActionResult CustomerIndex(String keyword)
        {
          //  var sections;
           
            if (string.IsNullOrEmpty(keyword))
            {
                var sections =
                    db.Sections.Include(s => s.Course)
                        .Include(s => s.Faculty)
                        .Include(s => s.Room)
                        .Include(s => s.Schedule);
                 return View(sections.ToList());
            }
           return (View(db.Sections.Include(s => s.Course).Include(s => s.Faculty).Include(s => s.Room).Include(s => s.Schedule).Where(e=>e.Course.CourseName.Contains(keyword)).ToList()));
           // return View(sections.ToList());
        }

        // GET: Sections/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Section section = db.Sections.Find(id);
            if (section == null)
            {
                return HttpNotFound();
            }
            return View(section);
        }

        // GET: Sections/Details/5
        public ActionResult CustomerDetails(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Section section = db.Sections.Find(id);
            if (section == null)
            {
                return HttpNotFound();
            }
            return View(section);
        }

        // GET: Sections/Create
        public ActionResult Create()
        {
        

            var course = db.Courses.Where(s => s.CourseCode!= null)
                  .Select(s => new SelectListItem
                  {
                      Value = s.Id.ToString(),
                      Text = s.CourseCode + "-- " + s.CourseName.ToString()
                  });

            var faculty = db.Faculties.Where(s => s.FullName != null)
              .Select(s => new SelectListItem
              {
                  Value = s.Id.ToString(),
                  Text = s.Title + " " + s.FullName.ToString()
              });


            var schedule = db.Schedules.Where(s => s.FromDate!=null)
              .Select(s => new SelectListItem
              {
                  Value = s.Id.ToString(),
                  Text = s.Semester.SemesterName + " " + s.FromDate+"-"+s.ToDate
              });

            ViewBag.CourseId = new SelectList(course, "Value", "Text");

      
            ViewBag.FacultyId = new SelectList(faculty, "value", "Text");
            ViewBag.RoomId = new SelectList(db.Rooms, "Id", "RoomNo");
            ViewBag.ScheduleId = new SelectList(schedule, "value", "Text");
            return View();
        }
        

        // POST: Sections/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,ScheduleId,CourseId,FacultyId,RoomId,price,Capacity")] Section section)
        {
            if (ModelState.IsValid)
            {
                db.Sections.Add(section);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            //ViewBag.CourseId = new SelectList(db.Courses, "Id", "CourseCode", section.CourseId);
            //ViewBag.FacultyId = new SelectList(db.Faculties, "Id", "Title", section.FacultyId);
            //ViewBag.RoomId = new SelectList(db.Rooms, "Id", "RoomNo", section.RoomId);
            //ViewBag.ScheduleId = new SelectList(db.Schedules, "Id", "Id", section.ScheduleId);

            var course = db.Courses.Where(s => s.CourseCode != null)
                  .Select(s => new SelectListItem
                  {
                      Value = s.Id.ToString(),
                      Text = s.CourseCode + "-- " + s.CourseName.ToString()
                  });

            var faculty = db.Faculties.Where(s => s.FullName != null)
              .Select(s => new SelectListItem
              {
                  Value = s.Id.ToString(),
                  Text = s.Title + " " + s.FullName.ToString()
              });


            var schedule = db.Schedules.Where(s => s.FromDate != null)
              .Select(s => new SelectListItem
              {
                  Value = s.Id.ToString(),
                  Text = s.Semester.SemesterName + " " + s.FromDate + "-" + s.ToDate
              });

            ViewBag.CourseId = new SelectList(course, "Value", "Text");


            ViewBag.FacultyId = new SelectList(faculty, "value", "Text");
            ViewBag.RoomId = new SelectList(db.Rooms, "Id", "RoomNo");
            ViewBag.ScheduleId = new SelectList(schedule, "value", "Text");
            return View(section);
        }

        // GET: Sections/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Section section = db.Sections.Find(id);
            if (section == null)
            {
                return HttpNotFound();
            }
            //ViewBag.CourseId = new SelectList(db.Courses, "Id", "CourseCode", section.CourseId);
            //ViewBag.FacultyId = new SelectList(db.Faculties, "Id", "Title", section.FacultyId);
            //ViewBag.RoomId = new SelectList(db.Rooms, "Id", "RoomNo", section.RoomId);
            //ViewBag.ScheduleId = new SelectList(db.Schedules, "Id", "Id", section.ScheduleId);


            var course = db.Courses.Where(s => s.CourseCode != null)
                  .Select(s => new SelectListItem
                  {
                      Value = s.Id.ToString(),
                      Text = s.CourseCode + "-- " + s.CourseName.ToString()
                  });

            var faculty = db.Faculties.Where(s => s.FullName != null)
              .Select(s => new SelectListItem
              {
                  Value = s.Id.ToString(),
                  Text = s.Title + " " + s.FullName.ToString()
              });


            var schedule = db.Schedules.Where(s => s.FromDate != null)
              .Select(s => new SelectListItem
              {
                  Value = s.Id.ToString(),
                  Text = s.Semester.SemesterName + " " + s.FromDate + "-" + s.ToDate
              });

            ViewBag.CourseId = new SelectList(course, "Value", "Text");


            ViewBag.FacultyId = new SelectList(faculty, "value", "Text");
            ViewBag.RoomId = new SelectList(db.Rooms, "Id", "RoomNo");
            ViewBag.ScheduleId = new SelectList(schedule, "value", "Text");
            return View(section);
        }

        // POST: Sections/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,ScheduleId,CourseId,FacultyId,RoomId,price,Capacity")] Section section)
        {
            if (ModelState.IsValid)
            {
                db.Entry(section).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            //ViewBag.CourseId = new SelectList(db.Courses, "Id", "CourseCode", section.CourseId);
            //ViewBag.FacultyId = new SelectList(db.Faculties, "Id", "Title", section.FacultyId);
            //ViewBag.RoomId = new SelectList(db.Rooms, "Id", "RoomNo", section.RoomId);
            //ViewBag.ScheduleId = new SelectList(db.Schedules, "Id", "Id", section.ScheduleId);


            var course = db.Courses.Where(s => s.CourseCode != null)
                  .Select(s => new SelectListItem
                  {
                      Value = s.Id.ToString(),
                      Text = s.CourseCode + "-- " + s.CourseName.ToString()
                  });

            var faculty = db.Faculties.Where(s => s.FullName != null)
              .Select(s => new SelectListItem
              {
                  Value = s.Id.ToString(),
                  Text = s.Title + " " + s.FullName.ToString()
              });


            var schedule = db.Schedules.Where(s => s.FromDate != null)
              .Select(s => new SelectListItem
              {
                  Value = s.Id.ToString(),
                  Text = s.Semester.SemesterName + " " + s.FromDate + "-" + s.ToDate
              });

            ViewBag.CourseId = new SelectList(course, "Value", "Text");


            ViewBag.FacultyId = new SelectList(faculty, "value", "Text");
            ViewBag.RoomId = new SelectList(db.Rooms, "Id", "RoomNo");
            ViewBag.ScheduleId = new SelectList(schedule, "value", "Text");
            return View(section);
        }

        // GET: Sections/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Section section = db.Sections.Find(id);
            if (section == null)
            {
                return HttpNotFound();
            }


            return View(section);
        }

        // POST: Sections/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Section section = db.Sections.Find(id);
            db.Sections.Remove(section);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        [Authorize(Roles="Faculty, Admin")]
        public ActionResult ViewSections()
        {
            ViewBag.FacultyFullName = CurrentFaculty == null ? "Unknown" : CurrentFaculty.FullName;
            return View();
        }

        [Authorize(Roles = "Faculty, Admin")]
        public ActionResult _Sections()
        {
            var currentFaculty = facultyService.GetFacultyByLogInUserName(User.Identity.Name);
            return PartialView(sectionService
                .GetSectionsOfNextSemester(currentFaculty == null ? (int?)null : currentFaculty.Id)
                .ToList()
                .Select(o => (SectionViewModel)o));
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            sectionService.Dispose(disposing);
            facultyService.Dispose(disposing);
            base.Dispose(disposing);
        }

        // GET: Sections/Edit/5
        [Authorize]
        public ActionResult Register(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Section section = db.Sections.Find(id);

            UserManagementService userManagement = new UserManagementService();
            CustomerService customerService = new CustomerService();
            User user = userManagement.GetUser(User.Identity.Name);
            Customer customer = customerService.GetCustomerByUserId(user.UserId);
          
            Transcript t = db.Transcripts.Where(e => (e.SectionId == section.Id && e.CustomerId==customer.Id)).FirstOrDefault();
            if (t != null)
            {

                TempData["Error"] = "You Are Already registered in " + section.Course.CourseName;
               // TempData["Error"] = ViewBag.ERROR;
                return RedirectToAction("CustomerIndex");
                // return View("CustomerIndex");
            }
            Waitinglist wait = db.WaitingLists.Where(e => (e.SectionId == section.Id && e.CustomerId == customer.Id)).FirstOrDefault();
            if (wait != null)
            {

                TempData["Error"] = "You Are Already added to the waiting list of " + section.Course.CourseName;
                // TempData["Error"] = ViewBag.ERROR;
                return RedirectToAction("CustomerIndex");
                // return View("CustomerIndex");
            }
            WaiverRequest w = db.WaiverRequests.Where(e =>(e.CustomerId == customer.Id && e.Status == WaiverRequestStatus.Approved &&e.CourseId == section.Course.PrerequisiteId)).FirstOrDefault();
            t = db.Transcripts.Where(e => ((e.Section.CourseId == section.Course.PrerequisiteId) && e.CustomerId == customer.Id)).FirstOrDefault();
            if ((t == null || w == null) && section.Course.PrerequisiteId!=null)
            {
                TempData["Waiver"] = 1;
                TempData["Error"] = "You Need To Waive " + section.Course.Prerequisite.CourseName;
                return RedirectToAction("CustomerIndex");
                // return View("CustomerIndex");
            }

            Transcript trans = new Transcript();
            trans.SectionId = section.Id;
            trans.Section = section;
            
            trans.CustomerId = user.UserId;
            trans.Customer = customer;

            if (section == null)
            {
                return HttpNotFound();
            }
            ViewBag.CourseId = new SelectList(db.Courses, "Id", "CourseCode", section.CourseId);
            ViewBag.FacultyId = new SelectList(db.Faculties, "Id", "Title", section.FacultyId);
            ViewBag.RoomId = new SelectList(db.Rooms, "Id", "RoomNo", section.RoomId);
            ViewBag.ScheduleId = new SelectList(db.Schedules, "Id", "Id", section.ScheduleId);

            return View(trans);
        }

        // POST: Sections/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Register([Bind(Include = "Id,ScheduleId,CourseId,FacultyId,RoomId,price")] Section section)
        {

            //if (ModelState.IsValid)
            //{
            //    db.Entry(section).State = EntityState.Modified;
            //    db.SaveChanges();
            //    return RedirectToAction("Index");
            //}
            ViewBag.CourseId = new SelectList(db.Courses, "Id", "CourseCode", section.CourseId);
            ViewBag.FacultyId = new SelectList(db.Faculties, "Id", "Title", section.FacultyId);
            ViewBag.RoomId = new SelectList(db.Rooms, "Id", "RoomNo", section.RoomId);
            ViewBag.ScheduleId = new SelectList(db.Schedules, "Id", "Id", section.ScheduleId);
            return View();
        }

        [HttpGet]
        [Authorize]
        public ActionResult PaymentForCourse(int id)
        {
            
            ViewBag.SectionId = id;
            return View();
        }

        [HttpPost]
        [Authorize]
        public ActionResult PaymentForCourse(CoursePaymentViewModel model)
        {
            if (ModelState.IsValid)
            {
                Section section = db.Sections.Find(model.SectionId);
                Customer currentCustomer = db.Customers.FirstOrDefault(x => x.User.UserName == User.Identity.Name);

                var transcriptModel = new Transcript()
                {
                    CourseDate = section.Schedule.FromDate,
                    CustomerId = currentCustomer.Id,
                    SectionId = model.SectionId,
                    Grade = 0,
                    CoursePaymentDetail = new CoursePaymentDetail
                    {
                        BillingAddress1 = model.BillingAddress1,
                        PrintedNameOnCard = model.PrintedNameOnCard,
                        Pin = model.Pin,
                        ExpiryDate = model.ExpiryDate,
                        CreditCardNumber = model.CreditCardNumber,
                        BillingProvience = model.BillingProvience,
                        BillingPostalCode = model.BillingPostalCode,
                        BillingCountry = model.BillingCountry,
                        BillingCity = model.BillingCity,
                        BillingAddress2 = model.BillingAddress2,
                    }
                };
                section.Capacity--;
                db.Entry(section).State = EntityState.Modified;
                db.Transcripts.Add(transcriptModel);
                db.SaveChanges();
                TempData["Error"] = "Sucessfuly enrolled in " + section.Course.CourseName;
             
               
            }
            return RedirectToAction("CustomerIndex");
        }
        [HttpGet]
        [Authorize]
        public ActionResult AddToWaittingList(int id)
        {
            ViewBag.SectionId = id;
            Section section = db.Sections.Find(id);
            Customer currentCustomer = db.Customers.FirstOrDefault(x => x.User.UserName == User.Identity.Name);

            Waitinglist wait = new Waitinglist()
            {
                CustomerId = currentCustomer.Id,
                SectionId = section.Id,
                Waitingdate = DateTime.Now.Date

            };
            db.WaitingLists.Add(wait);
            db.SaveChanges();
           
            return View();
        }

    }
}
